<?php
/**
* 合同控制器
*/

declare (strict_types = 1);

namespace app\controller\contract;

use app\BaseController;
use app\model\contract\Contract as ContractModel;
use app\service\WorkflowService;
use think\facade\Db;
use think\facade\Log;
use think\facade\Request;
use think\App;

class Contract extends BaseController
{
/**
* 合同模型实例
* @var ContractModel
*/
protected $contractModel;

/**
* 构造函数
* @param App $app 应用实例
*/
public function __construct(App $app)
{
parent::__construct($app);
$this->contractModel = new ContractModel();
}

/**
* 获取当前登录用户ID
* @return int
*/
protected function getUserId(): int
{
// 使用父类的方法获取用户ID
return parent::getUserId();
}

/**
* 查看合同列表
*/
public function list()
{
$param = Request::param();
$page = isset($param['page']) ? (int)$param['page'] : 1;
$limit = isset($param['limit']) ? (int)$param['limit'] : 10;

try {
// 恢复查询条件
$where = [];
$where[] = ['c.delete_time', '=', 0];
$where[] = ['c.archive_time', '=', 0];
$where[] = ['c.stop_time', '=', 0];
$where[] = ['c.void_time', '=', 0];

// 关键词搜索
if (!empty($param['keywords'])) {
$keywords = trim($param['keywords']);
$where[] = ['c.name|c.code|c.customer', 'exp', Db::raw("LIKE '%{$keywords}%'")];
}

// 按合同分类筛选
if (!empty($param['cate_id'])) {
$where[] = ['c.cate_id', '=', $param['cate_id']];
}

// 按客户筛选
if (!empty($param['customer_id'])) {
$where[] = ['c.customer_id', '=', $param['customer_id']];
}

// 按合同类型筛选
if (!empty($param['types'])) {
$where[] = ['c.types', '=', $param['types']];
}

// 按审核状态筛选
if (!empty($param['check_status'])) {
$where[] = ['c.check_status', '=', $param['check_status']];
}

// 按合同金额对比筛选
if (!empty($param['cost_diff'])) {
if ($param['cost_diff'] == '1') {
$where[] = ['c.cost', '=', Db::raw('c.cost2')];
} else {
$where[] = ['c.cost', '>', Db::raw('c.cost2')];
}
}

// 按后期费用筛选
if (!empty($param['cost3'])) {
if ($param['cost3'] == '1') {
$where[] = ['c.cost3', '<>', ''];
} else {
$where[] = ['c.cost3', '=', ''];
}
}

// 按款项结清状态筛选
if (isset($param['is_cleared']) && $param['is_cleared'] !== '') {
if ($param['is_cleared'] == '1') {
$where[] = ['c.cost', '=', Db::raw('c.cost2')]; // 款项结清：合同金额 = 到账金额
} else {
$where[] = ['c.cost', '<>', Db::raw('c.cost2')]; // 款项未结清：合同金额 != 到账金额
}
}

// 按是否有后期费用筛选
if (isset($param['has_cost3']) && $param['has_cost3'] !== '') {
if ($param['has_cost3'] == '1') {
$where[] = ['c.cost3', '<>', '']; // 有后期费用：后期费用不为空
} else {
$where[] = ['c.cost3', '=', '']; // 无后期费用：后期费用为空
}
}

// 按签订时间筛选
if (!empty($param['sign_time'])) {
$signTime = explode('~', $param['sign_time']);
$where[] = ['c.sign_time', 'between', [strtotime(urldecode($signTime[0])), strtotime(urldecode($signTime[1].' 23:59:59'))]];
}

// 按结束时间筛选
if (!empty($param['end_time'])) {
$endTime = explode('~', $param['end_time']);
$where[] = ['c.end_time', 'between', [strtotime(urldecode($endTime[0])), strtotime(urldecode($endTime[1].' 23:59:59'))]];
}

// 按合同金额区间筛选
if (!empty($param['min_amount']) || !empty($param['max_amount'])) {
if (!empty($param['min_amount'])) {
    $where[] = ['c.cost', '>=', (float)$param['min_amount']];
}
if (!empty($param['max_amount'])) {
    $where[] = ['c.cost', '<=', (float)$param['max_amount']];
}
}

// 按到账金额区间筛选
if (!empty($param['min_cost2']) || !empty($param['max_cost2'])) {
if (!empty($param['min_cost2'])) {
    $where[] = ['c.cost2', '>=', (float)$param['min_cost2']];
}
if (!empty($param['max_cost2'])) {
    $where[] = ['c.cost2', '<=', (float)$param['max_cost2']];
}
}

// 按签约日期区间筛选
if (!empty($param['sign_start_time']) || !empty($param['sign_end_time'])) {
if (!empty($param['sign_start_time'])) {
    $startTime = strtotime(urldecode($param['sign_start_time']));
    if ($startTime !== false) {
        $where[] = ['c.sign_time', '>=', $startTime];
    }
}
if (!empty($param['sign_end_time'])) {
    $endTime = strtotime(urldecode($param['sign_end_time'] . ' 23:59:59'));
    if ($endTime !== false) {
        $where[] = ['c.sign_time', '<=', $endTime];
    }
}
}

// 按签约人姓名筛选
if (!empty($param['sign_name'])) {
$where[] = ['sa.name', 'like', '%' . trim($param['sign_name']) . '%'];
}

// 按是否到期筛选
if (isset($param['is_expired']) && $param['is_expired'] !== '') {
if ($param['is_expired'] == '1') {
    // 已到期：结束时间小于当前时间
    $where[] = ['c.end_time', '<', time()];
} else {
    // 未到期：结束时间大于等于当前时间
    $where[] = ['c.end_time', '>=', time()];
}
}

// 使用模型获取合同列表
$result = $this->contractModel->getContractList($where, $page, $limit);
$count = $this->contractModel->getContractList($where, 0, 0)['count'];

return json([
'code' => 0,
'msg' => 'success',
'data' => $this->ensureIntegerTimestamps($result),
'count' => $count
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 确保时间字段保持整数格式
* @param array $data 数据数组
* @return array 处理后的数据
*/
private function ensureIntegerTimestamps($data)
{
    // 需要保持整数格式的时间字段
    $timeFields = [
        'create_time', 'update_time', 'sign_time', 'start_time', 'end_time',
        'archive_time', 'stop_time', 'void_time', 'check_time', 'delete_time'
    ];
    
    // 处理数组和对象
    if (is_array($data)) {
        // 检查是否为索引数组
        if (isset($data['list']) && is_array($data['list'])) {
            foreach ($data['list'] as &$item) {
                $item = $this->ensureIntegerTimestamps($item);
            }
            unset($item);
            return $data;
        }
        
        // 处理普通对象
        foreach ($timeFields as $field) {
            if (isset($data[$field]) && $data[$field] !== null && $data[$field] !== '') {
                // 如果是日期格式的字符串，尝试转换为时间戳
                if (is_string($data[$field]) && !is_numeric($data[$field]) && preg_match('/^\d{4}-\d{2}-\d{2}/', $data[$field])) {
                    $timestamp = strtotime($data[$field]);
                    if ($timestamp !== false) {
                        $data[$field] = $timestamp;
                    }
                } else if (is_numeric($data[$field])) {
                    // 如果是数字字符串或数字，转换为整数
                    $data[$field] = (int)$data[$field];
                } else if (is_string($data[$field])) {
                    // 尝试将字符串转换为整数
                    $numericValue = filter_var($data[$field], FILTER_VALIDATE_INT);
                    if ($numericValue !== false) {
                        $data[$field] = $numericValue;
                    }
                }
            }
        }
        
        // 处理附件中的时间字段
        if (isset($data['attachments']) && is_array($data['attachments'])) {
            foreach ($data['attachments'] as &$attachment) {
                if (is_array($attachment)) {
                    foreach ($timeFields as $field) {
                        if (isset($attachment[$field]) && $attachment[$field] !== null && $attachment[$field] !== '') {
                            if (is_string($attachment[$field]) && !is_numeric($attachment[$field]) && preg_match('/^\d{4}-\d{2}-\d{2}/', $attachment[$field])) {
                                $timestamp = strtotime($attachment[$field]);
                                if ($timestamp !== false) {
                                    $attachment[$field] = $timestamp;
                                }
                            } else if (is_numeric($attachment[$field])) {
                                $attachment[$field] = (int)$attachment[$field];
                            } else if (is_string($attachment[$field])) {
                                // 尝试将字符串转换为整数
                                $numericValue = filter_var($attachment[$field], FILTER_VALIDATE_INT);
                                if ($numericValue !== false) {
                                    $attachment[$field] = $numericValue;
                                }
                            }
                        }
                    }
                }
            }
            unset($attachment);
        }
        
        // 处理其他可能的嵌套数组
        foreach ($data as $key => $value) {
            if (is_array($value) && !in_array($key, ['list', 'attachments'])) {
                $data[$key] = $this->ensureIntegerTimestamps($value);
            }
        }
    }
    
    return $data;
}

/**
* 查看单个合同信息
*/
public function view()
{
$param = Request::param();

if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

try {
// 使用模型获取合同详情
$contract = $this->contractModel->getContractDetail((int)$param['id']);

if (empty($contract)) {
return json(['code' => 404, 'msg' => '合同不存在']);
}

// 获取合同附件
try {
    $attachments = [];
    
    // 从合同记录的file_ids字段获取文件ID
    if (!empty($contract['file_ids'])) {
        $fileIds = explode(',', $contract['file_ids']);
        if (!empty($fileIds)) {
            // 从文件表中查询文件信息
            $files = Db::name('file')
                ->where('id', 'in', $fileIds)
                ->where('delete_time', 0)
                ->select()->toArray();
                
            // 处理文件路径，确保使用正斜杠
            foreach ($files as &$file) {
                // 解决文件路径中的反斜杠问题
                if (isset($file['filepath'])) {
                    $file['filepath'] = str_replace('\\', '/', $file['filepath']);
                }
                if (isset($file['filename'])) {
                    $file['filename'] = str_replace('\\', '/', $file['filename']);
                }
                // 确保时间字段不为空
                if (empty($file['create_time'])) {
                    $file['create_time'] = time();
                }
                // 确保文件大小字段不为空
                if (empty($file['filesize'])) {
                    $file['filesize'] = 0;
                }
            }
            unset($file); // 释放引用
            
            $attachments = $files;
        }
    }
    
    $contract['attachments'] = $attachments;
} catch (\Exception $e) {
    // 如果查询出错，则设置为空数组
    $contract['attachments'] = [];
    // 记录错误日志
    Log::error('获取合同文件失败: ' . $e->getMessage());
}

// 获取合同共享人员
try {
    $sharers = [];
    // 从contract表的share_ids获取共享人信息
    if (!empty($contract['share_ids'])) {
        $shareIds = explode(',', $contract['share_ids']);
        if (!empty($shareIds)) {
            $sharers = Db::name('admin')
                ->where('id', 'in', $shareIds)
                ->field('id as share_uid, name')
                ->select()->toArray();
        }
    }
    
    $contract['sharers'] = $sharers;

    // 获取共享人员姓名拼接字符串
    if (!empty($contract['share_ids'])) {
        $shareNames = Db::name('admin')
            ->where('id', 'in', explode(',', $contract['share_ids']))
            ->column('name');
        $contract['share_names'] = implode(',', $shareNames);
    }
} catch (\Exception $e) {
    // 如果查询出错，则设置为空数组
    $contract['sharers'] = [];
    $contract['share_names'] = '';
    // 记录错误日志
    Log::error('获取合同共享人员失败: ' . $e->getMessage());
}

// 获取当前审批人姓名
if (!empty($contract['check_uids'])) {
$checkNames = Db::name('admin')
->where('id', 'in', explode(',', $contract['check_uids']))
->column('name');
$contract['check_names'] = implode(',', $checkNames);

// 获取合同审批人详情
$approvers = Db::name('admin')
->where('id', 'in', explode(',', $contract['check_uids']))
->field('id, name')
->select()->toArray();
$contract['approvers'] = $approvers;
}

// 获取历史审批人姓名
if (!empty($contract['check_history_uids'])) {
$historyNames = Db::name('admin')
->where('id', 'in', explode(',', $contract['check_history_uids']))
->column('name');
$contract['history_names'] = implode(',', $historyNames);
}

// 获取抄送人姓名
if (!empty($contract['check_copy_uids'])) {
$copyNames = Db::name('admin')
->where('id', 'in', explode(',', $contract['check_copy_uids']))
->column('name');
$contract['copy_names'] = implode(',', $copyNames);
}

// 获取合同类别名称
if (!empty($contract['cate_id'])) {
    $contract['cate_title'] = Db::name('contract_cate')
        ->where('id', $contract['cate_id'])
        ->value('title');
}

// 获取签约主体名称
if (!empty($contract['subject_id'])) {
$contract['subject_title'] = Db::name('enterprise')
->where('id', $contract['subject_id'])
->value('title');
}

// 获取合同制定人姓名
if (!empty($contract['prepared_uid'])) {
$contract['prepared_name'] = Db::name('admin')
->where('id', $contract['prepared_uid'])
->value('name');
}

// 获取录入人姓名
if (!empty($contract['admin_id'])) {
$contract['admin_name'] = Db::name('admin')
->where('id', $contract['admin_id'])
->value('name');
}

// 获取合同签订人姓名
if (!empty($contract['sign_uid'])) {
$contract['sign_name'] = Db::name('admin')
->where('id', $contract['sign_uid'])
->value('name');

// 获取签约人所属部门
$signAdmin = Db::name('admin')
->alias('a')
->join('department d', 'a.did = d.id', 'LEFT')
->where('a.id', $contract['sign_uid'])
->field('d.id as department_id, d.title as sign_department')
->find();

if (!empty($signAdmin)) {
    $contract['sign_department'] = $signAdmin['sign_department'] ?: '未设置部门';
    $contract['department_id'] = $signAdmin['department_id'] ?: 0;
} else {
    $contract['sign_department'] = '未设置部门';
    $contract['department_id'] = 0;
}
}

// 获取合同保管人姓名
if (!empty($contract['keeper_uid'])) {
$contract['keeper_name'] = Db::name('admin')
->where('id', $contract['keeper_uid'])
->value('name');
}

// 获取中止人姓名
if (!empty($contract['stop_uid'])) {
$contract['stop_name'] = Db::name('admin')
->where('id', $contract['stop_uid'])
->value('name');
}

// 获取作废人姓名
if (!empty($contract['void_uid'])) {
$contract['void_name'] = Db::name('admin')
->where('id', $contract['void_uid'])
->value('name');
}

// 获取归档人姓名
if (!empty($contract['archive_uid'])) {
$contract['archive_name'] = Db::name('admin')
->where('id', $contract['archive_uid'])
->value('name');
}

// 获取律所名称
if (!empty($contract['lawfirm_id'])) {
$contract['lawfirm_name'] = Db::name('lawyer')
->where('id', $contract['lawfirm_id'])
->value('name');
}

// 获取律师名称
if (!empty($contract['lawyer_id'])) {
$contract['lawyer_name'] = Db::name('lawyer')
->where('id', $contract['lawyer_id'])
->value('name');
}

// 获取合同内容（如果是商品合同或服务合同）
if ($contract['types'] > 1 && !empty($contract['content'])) {
$contract['content'] = unserialize($contract['content']);
}

// 获取客户详细地址（省市区+详细地址）
if (!empty($contract['customer_id'])) {
    $customer = Db::name('customer')->where('id', $contract['customer_id'])->find();
    if ($customer) {
        // 获取省市区名称
        $provinceName = '';
        $cityName = '';
        $distName = '';
        
        if (!empty($customer['provinceid'])) {
            $provinceName = Db::name('region')->where('id', $customer['provinceid'])->value('name');
        }
        
        if (!empty($customer['cityid'])) {
            $cityName = Db::name('region')->where('id', $customer['cityid'])->value('name');
        }
        
        if (!empty($customer['distid'])) {
            $distName = Db::name('region')->where('id', $customer['distid'])->value('name');
        }
        
        // 拼接完整地址
        $fullAddress = '';
        if ($provinceName) {
            $fullAddress .= $provinceName;
        }
        if ($cityName) {
            $fullAddress .= $cityName;
        }
        if ($distName) {
            $fullAddress .= $distName;
        }
        if (!empty($customer['address'])) {
            $fullAddress .= $customer['address'];
        }
        
        $contract['contact_address'] = $fullAddress;
    }
}

return json([
'code' => 0,
'msg' => 'success',
'data' => $this->ensureIntegerTimestamps($contract)
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 新建合同
*/
public function add()
{
$param = Request::param();
$userId = $this->getUserId();

// 参数验证
if (empty($param['name'])) {
return json(['code' => 400, 'msg' => '合同名称不能为空']);
}

if (empty($param['customer_id'])) {
return json(['code' => 400, 'msg' => '客户不能为空']);
}

if (empty($param['types'])) {
return json(['code' => 400, 'msg' => '合同类型不能为空']);
}

// 处理时间参数
// 确保时间字段始终有有效的值，即使用户没有提供
$today = strtotime(date('Y-m-d')); // 今天的零点
$nextYear = strtotime(date('Y-m-d', strtotime('+1 year'))); // 一年后的今天

$signTime = !empty($param['sign_time']) ? strtotime($param['sign_time']) : $today;
$startTime = !empty($param['start_time']) ? strtotime($param['start_time']) : $today;
$endTime = !empty($param['end_time']) ? strtotime($param['end_time']) : $nextYear;

// 验证时间逻辑
if ($endTime > 0 && $startTime > 0 && $endTime <= $startTime) {
return json(['code'=> 400, 'msg' => '结束时间需要大于开始时间']);
}

// 处理合同内容（商品合同或服务合同）
$content = [];
if (!empty($param['product_list'])) {
$content = json_decode($param['product_list'], true);
} else {
if ($param['types'] == 2) {
// 商品合同
$productTitleData = isset($param['product_title']) ? $param['product_title'] : '';
$productIdData = isset($param['product_id']) ? $param['product_id'] : 0;
$productUnitData = isset($param['product_unit']) ? $param['product_unit'] : '';
$productSpecsData = isset($param['product_specs']) ? $param['product_specs'] : '';
$productPriceData = isset($param['product_price']) ? $param['product_price'] : '0.00';
$productNumData = isset($param['product_num']) ? $param['product_num'] : 1;
$productSubtotalData = isset($param['product_subtotal']) ? $param['product_subtotal'] : '0.00';
$productRemarkData = isset($param['product_remark']) ? $param['product_remark'] : '';

$product = [];
if (!empty($productTitleData)) {
foreach ($productTitleData as $key => $value) {
if (!$value) {
continue;
}
$data = [];
$data['product_title'] = $productTitleData[$key];
$data['product_id'] = $productIdData[$key];
$data['product_unit'] = $productUnitData[$key];
$data['product_specs'] = $productSpecsData[$key];
$data['product_price'] = $productPriceData[$key];
$data['product_num'] = $productNumData[$key];
$data['product_subtotal'] = $productSubtotalData[$key];
$data['product_remark'] = $productRemarkData[$key];
$product[] = $data;
}
}
$content = serialize($product);
} else if ($param['types'] == 3) {
// 服务合同
$serviceTitleData = isset($param['service_title']) ? $param['service_title'] : '';
$serviceIdData = isset($param['service_id']) ? $param['service_id'] : 0;
$serviceDateData = isset($param['service_date']) ? $param['service_date'] : '';
$servicePriceData = isset($param['service_price']) ? $param['service_price'] : '0.00';
$serviceNumData = isset($param['service_num']) ? $param['service_num'] : 1;
$serviceSubtotalData = isset($param['service_subtotal']) ? $param['service_subtotal'] : '0.00';
$serviceRemarkData = isset($param['service_remark']) ? $param['service_remark'] : '';

$service = [];
if (!empty($serviceTitleData)) {
foreach ($serviceTitleData as $key => $value) {
if (!$value) {
continue;
}
$data = [];
$data['service_title'] = $serviceTitleData[$key];
$data['service_id'] = $serviceIdData[$key];
$data['service_date'] = $serviceDateData[$key];
$data['service_price'] = $servicePriceData[$key];
$data['service_num'] = $serviceNumData[$key];
$data['service_subtotal'] = $serviceSubtotalData[$key];
$data['service_remark'] = $serviceRemarkData[$key];
$service[] = $data;
}
}
$content = serialize($service);
} else {
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
}
}

// 确保content字段始终是JSON格式
if (!is_string($content)) {
    $content = json_encode($content, JSON_UNESCAPED_UNICODE);
}

$data = [
'pid' => $param['pid'] ?? 0,
'code' => $this->contractModel->generateContractCode($param['code'] ?? null),
'name' => $param['name'],
'cate_id' => $param['cate_id'] ?? 0,
'types' => $param['types'],
'subject_id' => $param['subject_id'] ?? '',
'customer_id' => $param['customer_id'],
'customer' => $param['customer'] ?? '',
'contact_name' => $param['contact_name'] ?? '',
'contact_mobile' => $param['contact_mobile'] ?? '',
'contact_address' => $param['contact_address'] ?? '',
'start_time' => $startTime,
'end_time' => $endTime,
'admin_id' => $userId,
'prepared_uid' => $param['prepared_uid'] ?? 0,
'sign_uid' => $param['sign_uid'] ?? 0,
'keeper_uid' => $param['keeper_uid'] ?? 0,
'share_ids' => $param['share_ids'] ?? '',
'file_ids' => $param['file_ids'] ?? '',
'sign_time' => $signTime,
'did' => $param['did'] ?? 0,
'cost' => $param['cost'] ?? 0.00,
'content' => $content,
'cost2' => $param['cost2'] ?? 0.00,
'cost3' => $param['cost3'] ?? '',
'lawfirm_id' => $param['lawfirm_id'] ?? 0,
'lawyer_id' => $param['lawyer_id'] ?? 0,
'is_tax' => $param['is_tax'] ?? 0,
'tax' => $param['tax'] ?? 0.00,
'remark' => $param['remark'] ?? '',
'check_status' => 0,
'create_time' => time(),
'update_time' => time()
];

try {
// 使用模型创建合同
$contractId = $this->contractModel->createContract($data);

// 集成工作流审批系统
$this->integrateContractWorkflow($contractId, $data);

return json(['code' => 0, 'msg' => '添加成功', 'data' => ['id' => $contractId]]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '添加失败: ' . $e->getMessage()]);
}
}

/**
* 编辑合同
*/
public function edit()
{
$param = Request::param();

if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

if (empty($param['name'])) {
return json(['code' => 400, 'msg' => '合同名称不能为空']);
}

// 处理时间参数
// 确保时间字段始终有有效的值，即使用户没有提供
$today = strtotime(date('Y-m-d')); // 今天的零点
$nextYear = strtotime(date('Y-m-d', strtotime('+1 year'))); // 一年后的今天

$signTime = !empty($param['sign_time']) ? strtotime($param['sign_time']) : $today;
$startTime = !empty($param['start_time']) ? strtotime($param['start_time']) : $today;
$endTime = !empty($param['end_time']) ? strtotime($param['end_time']) : $nextYear;

// 验证时间逻辑
if ($endTime > 0 && $startTime > 0 && $endTime <= $startTime) {
return json(['code'=> 400, 'msg' => '结束时间需要大于开始时间']);
}

// 处理合同内容（商品合同或服务合同）
$content = [];
if (!empty($param['product_list'])) {
$content = json_decode($param['product_list'], true);
} else {
if ($param['types'] == 2) {
// 商品合同
$productTitleData = isset($param['product_title']) ? $param['product_title'] : '';
$productIdData = isset($param['product_id']) ? $param['product_id'] : 0;
$productUnitData = isset($param['product_unit']) ? $param['product_unit'] : '';
$productSpecsData = isset($param['product_specs']) ? $param['product_specs'] : '';
$productPriceData = isset($param['product_price']) ? $param['product_price'] : '0.00';
$productNumData = isset($param['product_num']) ? $param['product_num'] : 1;
$productSubtotalData = isset($param['product_subtotal']) ? $param['product_subtotal'] : '0.00';
$productRemarkData = isset($param['product_remark']) ? $param['product_remark'] : '';

$product = [];
if (!empty($productTitleData)) {
foreach ($productTitleData as $key => $value) {
if (!$value) {
continue;
}
$data = [];
$data['product_title'] = $productTitleData[$key];
$data['product_id'] = $productIdData[$key];
$data['product_unit'] = $productUnitData[$key];
$data['product_specs'] = $productSpecsData[$key];
$data['product_price'] = $productPriceData[$key];
$data['product_num'] = $productNumData[$key];
$data['product_subtotal'] = $productSubtotalData[$key];
$data['product_remark'] = $productRemarkData[$key];
$product[] = $data;
}
}
$content = serialize($product);
} else if ($param['types'] == 3) {
// 服务合同
$serviceTitleData = isset($param['service_title']) ? $param['service_title'] : '';
$serviceIdData = isset($param['service_id']) ? $param['service_id'] : 0;
$serviceDateData = isset($param['service_date']) ? $param['service_date'] : '';
$servicePriceData = isset($param['service_price']) ? $param['service_price'] : '0.00';
$serviceNumData = isset($param['service_num']) ? $param['service_num'] : 1;
$serviceSubtotalData = isset($param['service_subtotal']) ? $param['service_subtotal'] : '0.00';
$serviceRemarkData = isset($param['service_remark']) ? $param['service_remark'] : '';

$service = [];
if (!empty($serviceTitleData)) {
foreach ($serviceTitleData as $key => $value) {
if (!$value) {
continue;
}
$data = [];
$data['service_title'] = $serviceTitleData[$key];
$data['service_id'] = $serviceIdData[$key];
$data['service_date'] = $serviceDateData[$key];
$data['service_price'] = $servicePriceData[$key];
$data['service_num'] = $serviceNumData[$key];
$data['service_subtotal'] = $serviceSubtotalData[$key];
$data['service_remark'] = $serviceRemarkData[$key];
$service[] = $data;
}
}
$content = serialize($service);
} else {
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
}
}

// 确保content字段始终是JSON格式
if (!is_string($content)) {
    $content = json_encode($content, JSON_UNESCAPED_UNICODE);
}

$data = [
'id' => $param['id'],
'pid' => $param['pid'] ?? 0,
'name' => $param['name'],
'code' => $param['code'] ?? '',
'cate_id' => $param['cate_id'] ?? 0,
'types' => $param['types'] ?? 1,
'subject_id' => $param['subject_id'] ?? '',
'customer_id' => $param['customer_id'] ?? 0,
'customer' => $param['customer'] ?? '',
'contact_name' => $param['contact_name'] ?? '',
'contact_mobile' => $param['contact_mobile'] ?? '',
'contact_address' => $param['contact_address'] ?? '',
'start_time' => $startTime,
'end_time' => $endTime,
'prepared_uid' => $param['prepared_uid'] ?? 0,
'sign_uid' => $param['sign_uid'] ?? 0,
'keeper_uid' => $param['keeper_uid'] ?? 0,
'share_ids' => $param['share_ids'] ?? '',
'file_ids' => $param['file_ids'] ?? '',
'sign_time' => $signTime,
'did' => $param['did'] ?? 0,
'cost' => $param['cost'] ?? 0.00,
'content' => $content,
'cost2' => $param['cost2'] ?? 0.00,
'cost3' => $param['cost3'] ?? '',
'lawfirm_id' => $param['lawfirm_id'] ?? 0,
'lawyer_id' => $param['lawyer_id'] ?? 0,
'is_tax' => $param['is_tax'] ?? 0,
'tax' => $param['tax'] ?? 0.00,
'remark' => $param['remark'] ?? '',
'update_time' => time()
];

try {
// 使用模型更新合同
$result = $this->contractModel->updateContract((int)$param['id'], $data);

if (!$result) {
return json(['code' => 400, 'msg' => '更新失败，合同不存在']);
}

return json(['code' => 0, 'msg' => '编辑成功']);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '编辑失败: ' . $e->getMessage()]);
}
}

/**
* 删除合同（软删除）
*/
public function del()
{
$param = Request::param();

if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

try {
// 使用模型软删除合同
$result = $this->contractModel->deleteContract((int)$param['id']);

if (!$result) {
return json(['code' => 400, 'msg' => '删除失败，合同不存在']);
}

return json(['code' => 0, 'msg' => '删除成功']);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '删除失败: ' . $e->getMessage()]);
}
}

/**
* 归档合同列表
*/
public function archive_list()
{
$param = Request::param();
$page = isset($param['page']) ? (int)$param['page'] : 1;
$limit = isset($param['limit']) ? (int)$param['limit'] : 10;

// 构建查询条件
$where = [
['c.delete_time', '=', 0],
['c.archive_time', '>', 0]
];

// 关键词搜索
if (!empty($param['keywords'])) {
$keywords = trim($param['keywords']);
$where[] = ['c.name|c.code|c.customer', 'exp', Db::raw("LIKE '%{$keywords}%'")];
}

try {
// 使用模型获取归档合同列表
$list = $this->contractModel->getContractList($where, $page, $limit);
$count = $this->contractModel->getContractList($where, 0, 0)['count'];

// 查询归档操作人姓名
if (!empty($list['list'])) {
    foreach ($list['list'] as &$item) {
        if (!empty($item['archive_uid']) && $item['archive_uid'] > 0) {
            $item['archive_user'] = Db::name('admin')
                ->where('id', $item['archive_uid'])
                ->value('name');
        } else {
            $item['archive_user'] = '';
        }
    }
    unset($item);
}

return json([
'code' => 0,
'msg' => 'success',
'data' => $this->ensureIntegerTimestamps($list),
'count' => $count
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 中止合同列表
*/
public function stop_list()
{
$param = Request::param();
$page = isset($param['page']) ? (int)$param['page'] : 1;
$limit = isset($param['limit']) ? (int)$param['limit'] : 10;

// 构建查询条件
$where = [
['c.delete_time', '=', 0],
['c.stop_time', '>', 0]
];

// 关键词搜索
if (!empty($param['keywords'])) {
$keywords = trim($param['keywords']);
$where[] = ['c.name|c.code|c.customer', 'exp', Db::raw("LIKE '%{$keywords}%'")];
}

try {
// 使用模型获取中止合同列表
$list = $this->contractModel->getContractList($where, $page, $limit);
$count = $this->contractModel->getContractList($where, 0, 0)['count'];

// 查询中止操作人姓名
if (!empty($list['list'])) {
    foreach ($list['list'] as &$item) {
        if (!empty($item['stop_uid']) && $item['stop_uid'] > 0) {
            $item['stop_user'] = Db::name('admin')
                ->where('id', $item['stop_uid'])
                ->value('name');
        } else {
            $item['stop_user'] = '';
        }
    }
    unset($item);
}

return json([
'code' => 0,
'msg' => 'success',
'data' => $this->ensureIntegerTimestamps($list),
'count' => $count
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 作废合同列表
*/
public function void_list()
{
$param = Request::param();
$page = isset($param['page']) ? (int)$param['page'] : 1;
$limit = isset($param['limit']) ? (int)$param['limit'] : 10;

// 构建查询条件
$where = [
['c.delete_time', '=', 0],
['c.void_time', '>', 0]
];

// 关键词搜索
if (!empty($param['keywords'])) {
$where[] = ['c.name|c.code|c.customer', 'like', '%' . trim($param['keywords']) . '%'];
}

try {
// 使用模型获取作废合同列表
$list = $this->contractModel->getContractList($where, $page, $limit);
$count = $this->contractModel->getContractList($where, 0, 0)['count'];

// 查询作废操作人姓名
if (!empty($list['list'])) {
    foreach ($list['list'] as &$item) {
        if (!empty($item['void_uid']) && $item['void_uid'] > 0) {
            $item['void_user'] = Db::name('admin')
                ->where('id', $item['void_uid'])
                ->value('name');
        } else {
            $item['void_user'] = '';
        }
    }
    unset($item);
}

return json([
'code' => 0,
'msg' => 'success',
'data' => $this->ensureIntegerTimestamps($list),
'count' => $count
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 合同归档
*/
public function archive()
{
$param = Request::param();
$userId = $this->getUserId();

// 支持status参数用于取消归档
$status = isset($param['status']) ? (int)$param['status'] : 1;
            
if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

// 检查备注，归档和恢复操作都需要备注
if ($status == 0 && empty($param['archive_remark'])) {
return json(['code' => 400, 'msg' => '恢复备注不能为空']);
}

try {
// 根据status参数决定是归档还是取消归档
if ($status == 1) {
// 使用模型归档合同
$result = $this->contractModel->archiveContract((int)$param['id'], $userId);
$msg = '归档成功';
} else {
// 取消归档（恢复）
$result = $this->contractModel->unarchiveContractWithRemark((int)$param['id'], $userId, $param['archive_remark']);
$msg = '恢复成功';
}

if (!$result) {
return json(['code' => 400, 'msg' => ($status == 1 ? '归档失败' : '恢复失败') . '，合同不存在']);
}

return json(['code' => 0, 'msg' => $msg]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => ($status == 1 ? '归档失败' : '恢复失败') . ': ' . $e->getMessage()]);
}
}

/**
* 合同中止
*/
public function stop()
{
$param = Request::param();
$userId = $this->getUserId();

if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

// 获取status参数，默认为1（中止操作）
$status = isset($param['status']) ? (int)$param['status'] : 1;

// 检查备注，中止和恢复操作都需要备注
if (empty($param['stop_remark'])) {
return json(['code' => 400, 'msg' => ($status == 1 ? '中止' : '恢复') . '备注不能为空']);
}

try {
// 根据status参数决定是中止还是恢复
if ($status == 1) {
// 使用模型中止合同
$result = $this->contractModel->stopContract((int)$param['id'], $userId, $param['stop_remark']);
$msg = '中止成功';
} else {
// 恢复中止的合同
$result = $this->contractModel->unstopContract((int)$param['id'], $userId, $param['stop_remark']);
$msg = '恢复成功';
}

if (!$result) {
return json(['code' => 400, 'msg' => ($status == 1 ? '中止失败' : '恢复失败') . '，合同不存在']);
}

return json(['code' => 0, 'msg' => $msg]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => ($status == 1 ? '中止失败' : '恢复失败') . ': ' . $e->getMessage()]);
}
}

/**
* 合同作废
*/
public function void()
{
$param = Request::param();
$userId = $this->getUserId();

if (empty($param['id'])) {
return json(['code' => 400, 'msg' => '参数错误']);
}

// 获取status参数，默认为1（作废操作）
$status = isset($param['status']) ? (int)$param['status'] : 1;

// 检查备注，作废和恢复操作都需要备注
if (empty($param['void_remark'])) {
return json(['code' => 400, 'msg' => ($status == 1 ? '作废' : '恢复') . '备注不能为空']);
}

try {
// 根据status参数决定是作废还是恢复
if ($status == 1) {
// 使用模型作废合同
$result = $this->contractModel->voidContract((int)$param['id'], $userId, $param['void_remark']);
$msg = '作废成功';
} else {
// 恢复作废的合同
$result = $this->contractModel->unvoidContract((int)$param['id'], $userId, $param['void_remark']);
$msg = '恢复成功';
}

if (!$result) {
return json(['code' => 400, 'msg' => ($status == 1 ? '作废失败' : '恢复失败') . '，合同不存在']);
}

return json(['code' => 0, 'msg' => $msg]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => ($status == 1 ? '作废失败' : '恢复失败') . ': ' . $e->getMessage()]);
}
}

/**
* 处理合同审批
*/
public function processApproval()
{
$param = Request::param();
$userId = $this->getUserId();

if (empty($param['contract_id'])) {
return json(['code' => 400, 'msg' => '合同ID不能为空']);
}

if (empty($param['action'])) {
return json(['code' => 400, 'msg' => '审批动作不能为空']);
}

$contractId = (int)$param['contract_id'];
$action = (int)$param['action']; // 2=通过, 3=拒绝
$remark = trim($param['remark'] ?? '');

try {
// 查找对应的工作流审批记录
$approvalRecord = Db::name('workflow_approval')
->where('type', 'contract')
->where('business_id', $contractId)
->where('status', 'in', [0, 1]) // 待审批或审批中
->find();

if (!$approvalRecord) {
return json(['code' => 404, 'msg' => '未找到对应的审批记录']);
}

// 调用工作流服务处理审批
$workflowService = new WorkflowService();
$workflowService->processApproval($approvalRecord['id'], $userId, $action, $remark);

$actionText = $action == 2 ? '通过' : '拒绝';
return json(['code' => 0, 'msg' => '审批' . $actionText . '成功']);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '审批失败: ' . $e->getMessage()]);
}
}

/**
* 获取合同审批列表
*/
public function approvalList()
{
$param = Request::param();
$userId = $this->getUserId();
$page = isset($param['page']) ? (int)$param['page'] : 1;
$limit = isset($param['limit']) ? (int)$param['limit'] : 10;

try {
// 获取用户的待审批合同列表
$workflowService = new WorkflowService();
$result = $workflowService->getPendingApprovals($userId, [
'page' => $page,
'limit' => $limit,
'type' => 'contract'
]);

return json([
'code' => 0,
'msg' => 'success',
'data' => $result['list'],
'count' => $result['total']
]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
}
}

/**
* 集成合同工作流审批系统
* @param int $contractId 合同ID
* @param array $data 合同数据
*/
private function integrateContractWorkflow($contractId, $data)
{
try {
// 检查是否需要审批（使用模型方法）
if ($this->contractModel->contractNeedsApproval($data)) {
$workflowService = new WorkflowService();

// 获取审批人列表（使用模型方法）
$approvers = $this->contractModel->getContractApprovers($data);

if (!empty($approvers)) {
// 创建审批流程
$workflowService->createApproval(
'contract', // 审批类型
$contractId, // 业务ID
$data['admin_id'], // 申请人 ID
$approvers, // 审批人数组
$this->generateContractApprovalTitle($data), // 审批标题
$this->generateContractApprovalContent($data) // 审批内容
);

// 更新合同记录的审批状态
$this->contractModel->where('id', $contractId)->update([
'check_status' => 1, // 审批中
'check_uids' => implode(',', $approvers),
'update_time' => time()
]);
}
}
} catch (\Exception $e) {
// 工作流创建失败，记录日志但不影响主流程
Log::error('合同工作流创建失败: ' . $e->getMessage(), [
'contract_id' => $contractId,
'data' => $data
]);
}
}

/**
* 生成合同审批标题
* @param array $data
* @return string
*/
private function generateContractApprovalTitle($data)
{
$adminName = Db::name('admin')->where('id', $data['admin_id'])->value('name');
$cost = $data['cost'] ?? 0;
return "{$adminName}的合同审批申请（{$data['name']}，金额：¥{$cost}）";
}

/**
* 生成合同审批内容
* @param array $data
* @return array
*/
private function generateContractApprovalContent($data)
{
return [
'contract_name' => $data['name'],
'contract_code' => $data['code'],
'contract_type' => $data['types'] ?? 1,
'customer' => $data['customer'] ?? '',
'amount' => $data['cost'] ?? 0,
'sign_time' => $data['sign_time'] ?? 0,
'start_time' => $data['start_time'] ?? 0,
'end_time' => $data['end_time'] ?? 0,
'remark' => $data['remark'] ?? '',
'applicant_id' => $data['admin_id'],
'department_id' => $data['did'] ?? 0
];
}

/**
* 从合同直接创建案件
*/
public function create_case_from_contract()
{
$param = Request::param();
$contractId = $param['contract_id'] ?? 0;

// 参数验证
if (empty($contractId)) {
return json(['code' => 400, 'msg' => '合同ID不能为空']);
}

try {
// 使用模型获取合同信息
$contract = $this->contractModel->find($contractId);

if (!$contract) {
return json(['code' => 400, 'msg' => '合同不存在']);
}

// 检查合同是否已经关联了案件
$existingCase = Db::name('lawcase')
->where('contract_id', $contractId)
->where('delete_time', 0)
->find();

if ($existingCase) {
return json(['code' => 400, 'msg' => '该合同已关联案件，不能重复创建']);
}

// 生成案件编号
$caseCode = $this->generateCaseCodeFromContract($contract);

// 准备案件数据
$caseData = [
'case_code' => $caseCode,
'contract_id' => $contractId,
'case_type' => $this->getCaseTypeFromContract($contract),
'case_cause_id' => 0, // 需要用户后续填写
'court_id' => 0, // 需要用户后续填写
'main_lawyer' => $contract['lawyer_id'] ?? 0,
'secondary_lawyer' => 0,
'description' => $contract['name'] ?? '',
'session_time' => 0,
'status' => '准备阶段（未提交立案）',
'stage' => '（民）一审阶段',
'entrust_date' => date('Y-m-d'), // 默认为今天
'session_court_id' => 0,
'create_time' => time(),
'update_time' => time()
];

// 插入案件记录
$caseId = Db::name('lawcase')->insertGetId($caseData);

// 如果合同关联了客户，自动创建委托人当事人
if (!empty($contract['customer_id'])) {
$this->createClientPartyFromCustomer($caseId, $contract['customer_id']);
}

return json(['code' => 0, 'msg' => '案件创建成功', 'data' => ['id' => $caseId]]);
} catch (\Exception $e) {
return json(['code' => 500, 'msg' => '案件创建失败: ' . $e->getMessage()]);
}
}

/**
* 根据合同信息生成案件编号
* @param array $contract
* @return string
*/
protected function generateCaseCodeFromContract($contract)
{
// 生成案件编号的逻辑
$year = date('Y');
$month = date('m');

// 根据合同类型确定案件类型前缀
$caseTypePrefix = '民'; // 默认为民商事案件
if (strpos($contract['name'], '刑事') !== false) {
$caseTypePrefix = '刑';
} elseif (strpos($contract['name'], '行政') !== false) {
$caseTypePrefix = '行';
}

// 生成序号
$random = rand(1000, 9999);

return "{$year}（{$caseTypePrefix}）{$month}{$random}";
}

/**
* 根据合同信息确定案件类型
* @param array $contract
* @return string
*/
protected function getCaseTypeFromContract($contract)
{
// 根据合同类型确定案件类型
if (strpos($contract['name'], '刑事') !== false) {
return '刑事案件';
} elseif (strpos($contract['name'], '行政') !== false) {
return '行政案件';
} else {
return '民事案件';
}
}

/**
* 根据客户信息创建委托人当事人
* @param int $caseId
* @param int $customerId
* @return bool
*/
protected function createClientPartyFromCustomer($caseId, $customerId)
{
try {
// 查询客户信息
$customer = Db::name('customer')
->where('id', $customerId)
->where('delete_time', 0)
->find();

if (!$customer) {
return false;
}

// 检查该客户是否已经是当事人
$existingParty = Db::name('party')
->where('customer_id', $customerId)
->where('delete_time', 0)
->find();

if ($existingParty) {
$partyId = $existingParty['id'];
} else {
// 创建当事人记录
$partyData = [
'name' => $customer['name'] ?? '',
'party_type' => $customer['customer_type'] == 16 ? 2 : 1, // 16为企业，15为个人
'id_number' => '', // 客户表中没有证件号码字段
'legal_representative' => '', // 需要用户后续填写
'contact' => '', // 需要用户后续填写
'phone' => '', // 需要用户后续填写
'pid' => $customer['provinceid'] ?? 0,
'cid' => $customer['cityid'] ?? 0,
'did' => $customer['distid'] ?? 0,
'address' => $customer['address'] ?? '',
'customer_id' => $customerId,
'create_time' => time(),
'update_time' => time()
];

$partyId = Db::name('party')->insertGetId($partyData);
}

// 创建案件当事人关联记录
$lawcasePartyData = [
'case_id' => $caseId,
'party_id' => $partyId,
'is_client' => 1, // 委托人
'relationship' => '1', // 原告
'create_time' => time(),
'update_time' => time()
];

Db::name('lawcase_party')->insert($lawcasePartyData);

return true;
} catch (\Exception $e) {
// 记录错误但不中断主流程
return false;
}
}

/**
 * 获取有效的签约人列表（用于远程搜索）
 */
public function get_sign_users()
{
    $param = Request::param();
    $keywords = isset($param['keywords']) ? trim($param['keywords']) : '';
    $limit = isset($param['limit']) ? (int)$param['limit'] : 20;

    try {
        // 构建查询
        $query = Db::name('admin')
            ->field('id, name');

        // 如果有关键词，进行模糊搜索
        if (!empty($keywords)) {
            $query->where('name', 'like', '%' . $keywords . '%');
        }

        // 先获取总数，再获取列表
        $count = $query->count();
        $list = $query->limit($limit)->select()->toArray();

        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => $list,
            'count' => $count
        ]);
    } catch (\Exception $e) {
        return json(['code' => 500, 'msg' => '获取失败: ' . $e->getMessage()]);
    }
}

}